<?php
/***************************************************************
*  Copyright notice
*  (c) 2009, jianyuzhu@gmail.com
*  All rights reserved
*  This script is part of the PPEMI project.
***************************************************************/

//
include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'base.item.class.php');

class CoreCronBase extends BaseItemBase {
	
	//constructor
	function CoreCronBase() {
		parent::BaseItemBase();
		
		$this->table = 'pp_crons';
		$this->prefix = 'crons_';
		$this->sort_fields = array('sort_order+', 'name+');
		$this->filter_fields = array('status', 'nextrun', 'lock');
	}
	
	//methods
	function addItemB($data_array) {
		if( isset($data_array['crons_link']) ) {
			$item = $this->getItem($data_array['crons_link'], 'link');
			if( $item['crons_id'] > 0 ) {
				$this->updateItem($item['crons_id'], $data_array);
				return $item['crons_id'];
			} else {
				return $this->addItem($data_array);
			}
		}
		
		return 0;
	}
	
	function updateTime($items_id, $nexttime = '', $runtime = '') {
		if( $nexttime == '' ) {
			$nexttime = $this->_date_time() + 100000 * 1;
		} elseif( strpos($nexttime, '-') !== false ) {
			$nexttime = $this->_date_time($nexttime);
		} elseif( $nexttime == 'next_hour' ) {
			$nexttime = $this->_date_time(time() + 3600);
		} elseif( $nexttime == 'next_hour2' ) {
			$nexttime = $this->_date_time(time() + 7200);
		} elseif( $nexttime == 'next_hour3' ) {
			$nexttime = $this->_date_time(time() + 10800);
		} elseif( $nexttime == 'next_hour6' ) {
			$nexttime = $this->_date_time(time() + 21600);
		} elseif( $nexttime == 'next_hour12' ) {
			$nexttime = $this->_date_time(time() + 43200);
		} elseif( $nexttime == 'next_day' ) {
			$nexttime = $this->_date_time(time() + 86400);
		} elseif( substr($nexttime, 0, strlen('next_minute')) == 'next_minute' && substr($nexttime, strlen('next_minute')) > 0 ) {
			$nexttime = $this->_date_time(time() + 60 * substr($nexttime, strlen('next_minute')));
		} elseif( substr($nexttime, 0, strlen('next_hour')) == 'next_hour' && substr($nexttime, strlen('next_hour')) > 0 ) {
			$nexttime = $this->_date_time(time() + 3600 * substr($nexttime, strlen('next_hour')));
		} elseif( substr($nexttime, 0, strlen('next_day')) == 'next_day' && substr($nexttime, strlen('next_day')) > 0 ) {
			$nexttime = $this->_date_time(time() + 86400 * substr($nexttime, strlen('next_day')));
		} else {
			$nexttime = $this->_date_time(time() + 3600);
		}
		if( $runtime == '' ) {
			//$runtime = $this->_date_time();
			$runtime = 'now()';
		}
		
		$query = "update pp_crons set crons_nextrun = '" . $nexttime . "', crons_lastrun = '" . $runtime . "' where crons_id = '" . (int)$items_id . "'";
		
		return $this->adb->update($query);
	}
	
	function deleteItemA($item) {
		if( $item['crons_id'] > 0 ) {
			if( $item['crons_type'] == 'system' ) {
				return;
			}
			$this->deleteItem($items_id);
		}
	}
	
	function deleteItemB($items_id) {
		$item = $this->getItem($items_id);
		if( $item['crons_id'] > 0 && $item['crons_type'] == 'user' ) {
			$this->deleteItem($items_id);
		}
	}
		
	//
	function setItemsLock($items_ids, $lock = 1) {
		if( is_array($items_ids) ) {
			if( sizeof($items_ids) > 30 ) {
				foreach($items_ids as $k => $items_id) {
					$this->adb->update("update pp_crons set crons_lock = '" . (int)$lock . "' where crons_id = '" . (int)$items_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($items_ids)) . "'";
				$this->adb->update("update pp_crons set crons_lock = '" . (int)$lock . "' where crons_id in (" . $query_ids . ")");
			}
		}
	}
	
	//
	function run() {
		$filter = array('nextrun' => 'now', 'lock' => 0);
		$items = $this->getItems($filter);
		if( sizeof($items) == 0 ) {
			return true;
		}
		//lock
		$items_ids = $this->getListKey($items, 'crons_id');
		$this->setItemsLock($items_ids, 1);
		//
		for($i=0, $n=sizeof($items); $i<$n; $i++) {
			$crondir = CONFIG_PATH . CONFIG_DIR_CRONS;
			if( strlen($items[$i]['crons_filename']) > 0 && file_exists($crondir . $items[$i]['crons_filename']) ) {
				include_once($crondir . $items[$i]['crons_filename']);
				$cron_function = $items[$i]['crons_params'];
				
				if( $cron_function != '' && function_exists($cron_function) ) {
					call_user_func($cron_function);
					
					if( $items[$i]['crons_weekday'] > 0 ) {
						$nexttime = 'next_day' . '7';
					} elseif( $items[$i]['crons_day'] > 0 ) {
						$nexttime = 'next_day' . $items[$i]['crons_day'];
					} elseif( $items[$i]['crons_hour'] > 0 ) {
						$nexttime = 'next_hour' . $items[$i]['crons_hour'];
					} elseif( $items[$i]['crons_minute'] > 0 ) {
						$nexttime = 'next_minute' . $items[$i]['crons_minute'];
					} else {
						$nexttime = 'next_day';
					}
					
					$this->updateTime($items[$i]['crons_id'], $nexttime);
				}
			} elseif( strlen($items[$i]['crons_params']) > 0 && substr($items[$i]['crons_params'],0,5) == 'class' ) {
				//class:filename:classname:method:param1:param2...
				$a = explode(':', $items[$i]['crons_params']);
				if( sizeof($a) >= 4 ) {
					$this->loadclass($a['1']);
					$params = array_slice($a, 4);
					$this->call($a['2'], $a['3'], $params);
				}
			} elseif( strlen($items[$i]['crons_params']) > 0 && substr($items[$i]['crons_params'],0,8) == 'function' ) {
				//function:filename:functionname:param1:param2...
				$a = explode(':', $items[$i]['crons_params']);
				if( sizeof($a) >= 3 ) {
					$this->load($a['1'], 'function');
					$params = array_slice($a, 3);
					if( function_exists($a['2']) ) {
						call_user_func_array($a['2'], $params);
					}
				}
			}
		}
		//unlock
		$this->setItemsLock($items_ids, 0);
	}
	
	function updateNextRun($value, $type = 'link') {
		$data_array = array('_nextrun' => 'now()');
		$item = $this->getItem($value, $type);
		if( $item['crons_id'] > 0 ) {
			return $this->updateItem($item['crons_id'], $data_array);
		}
		
		return false;
	}
	
	//private
	function _get_query_str_custom($filter = '', $check = 0) {
		$query_str = "";
		if( is_array($filter) ) {
			$filter = func_db_input($filter);
			if( isset($filter['nextrun']) ) {
				if( $filter['nextrun'] == 'now' ) {
					$query_str .= " and crons_nextrun < now() ";
				} else {
					$query_str .= " and crons_nextrun < '" . $filter['nextrun'] . "' ";
				}
			}
			if( isset($filter['status']) ) {
				$query_str .= " and crons_status = '" . (int)$filter['status'] . "' ";
			}
			if( isset($filter['lock']) ) {
				$query_str .= " and crons_lock = '" . (int)$filter['lock'] . "' ";
			}
		}
		
		return $query_str;
	}
}
//
?>